import React, {useEffect, useRef, useState} from "react"
import {
    AntdTableColumnFilterSearches, buildSortCompareFunction, ExportedColumnProps, useTableSearchTextColumnProps
} from "../utils/AntdTableUtils";
import {ConfigProvider, Table, TableProps} from "antd";
import {NumberIdAndName} from "../types/BasicModels";
import {getAllGoodsBrand, GoodsBrandSummary} from "../apis/GoodsBrandsApi";
import {getAllGoodsCategories} from "../apis/GoodsCategoriesApi";
import {getAllFactory} from "../apis/FactoriesApi";
import {Response} from "@zxy-cn/fetcher";
import CancelablePromise from "cancelable-promise";
import {useGlobalStyle} from "../global.style";
import {useNavigate} from "react-router-dom";
import CopyButton from "./CopyButton";
import {CompareFn} from "antd/es/table/interface";
import {createUseStyles} from "react-jss";
import {cyan} from "@ant-design/colors";
import {TableRef} from "antd/es/table";

export interface GoodsTableProps<T> extends TableProps<T> {
    data: T[]
    customColumns?: (columns: ExportedColumnProps<T>[]) => ExportedColumnProps<T>[];
    brandsLoader?: () => CancelablePromise<Response<GoodsBrandSummary[]>>;
    categoriesLoader?: () => CancelablePromise<Response<NumberIdAndName[]>>;
    factoriesLoader?: () => CancelablePromise<Response<NumberIdAndName[]>>;
    localeSort?: boolean
    localeFilter?: boolean
}

export interface GoodsTableDataItem {
    name: string
    amount: number
    price: number
    barcode: string
    id: number
    brand?: NumberIdAndName
    category?: NumberIdAndName
    factory?: NumberIdAndName
    boxSpecification?: string
}

let useStyles = createUseStyles({
    highlight: () => ({
        color: cyan[4]
    }),
    singleLineCell:()=>({
        whiteSpace:"nowrap",
        overflow:"hidden",
        textOverflow:"ellipsis",
        width:"100%",
    }),
    copyableSingleLineCell:()=>({
       display:"flex",
       flexDirection:"row",
    }),
    copyableSingleLineCellText:()=>({
        whiteSpace:"nowrap",
        overflow:"hidden",
        textOverflow:"ellipsis",
        flex:1,
    }),
});

export const goodsTableColumnNames = [
    "名称", "条码", "品牌", "类别", "厂商", "库存", "零售价", "箱规", "数量", "总售价", "备案编号", "注册证编号",
];

function GoodsTable<T extends GoodsTableDataItem>(props: GoodsTableProps<T>) {
    const data = props.data;
    const [brands, setBrands] = useState<NumberIdAndName[]>([])
    const [categories, setCategories] = useState<NumberIdAndName[]>([])
    let styles = useStyles();

    const [factories, setFactories] = useState<NumberIdAndName[]>([])


    useEffect(() => {
        (props.brandsLoader ?? getAllGoodsBrand)().then(response => setBrands(response.data));
        (props.categoriesLoader ?? getAllGoodsCategories)().then(response => setCategories(response.data));
        (props.factoriesLoader ?? getAllFactory)().then(response => setFactories(response.data))
    }, [props.brandsLoader, props.categoriesLoader, props.factoriesLoader])
    let searchNameTableColumnProps = useTableSearchTextColumnProps<T>("name", {
        placeholder: "名字"
    });

    let barcodeSearchProps = useTableSearchTextColumnProps<T>("barcode", {
        placeholder: "条码"
    });

    function buildSortOptionUseFieldName(fieldName: keyof T) {
        return buildSortOption(buildSortCompareFunction(fieldName))

    }

    let localeSort = !props.onChange || props.localeSort;

    function buildSortOption(compareFunction: CompareFn<T>) {
        if (localeSort) {
            return compareFunction
        } else {
            return undefined
        }

    }

    let localeFilter = !props.onChange || !!props.localeFilter;
    const columns: ExportedColumnProps<T>[] = [
        {
            dataIndex: "barcode",
            title: "条码",
            ...barcodeSearchProps,
            onFilter: localeFilter ? (value, record) => {
                return record.barcode.toLowerCase().includes((value as string).toLowerCase())
            } : undefined,
            render: it => {
                return <div className={styles.copyableSingleLineCell} title={it}><span className={styles.copyableSingleLineCellText}>{it}</span><CopyButton value={it}/></div>
            },
            key: "barcode",
            sorter: localeSort ? buildSortOptionUseFieldName("barcode") : !!props.onChange,
            fixed: "left",
            width:140,
        },
        {
            dataIndex: "name",
            key: "name",
            title: "名称",
            ...searchNameTableColumnProps,
            onFilter: localeFilter ? (value, record) => {
                return record.name.toLowerCase().includes((value as string).toLowerCase())
            } : undefined,
            render: it => {
                return <div className={styles.copyableSingleLineCell} title={it}><span className={styles.copyableSingleLineCellText}>{it}</span><CopyButton value={it}/></div>
            },
            ellipsis:true,
            sorter: localeSort ? buildSortOptionUseFieldName("name") : !!props.onChange,
            fixed: "left",
            width: 240
        },
        {
            dataIndex: ["brand","name"],
            key: "brand",
            title: "品牌",
            filters: (localeFilter ? brands.filter(it => data.map(item => item.brand?.id).includes(it.id)) : brands).map(brand => {
                return {
                    text: brand.name,
                    value: brand.id,
                }
            }),
            defaultFilteredValue: [],
            filterSearch: AntdTableColumnFilterSearches.columnFilterByOptionText,
            onFilter: localeFilter ? (value, record) => {
                return record.brand?.id == value
            } : undefined,
            sorter: buildSortOption((a, b) => a.brand?.id ?? 0 - (b.brand?.id ?? 0)),
            ellipsis:true,
        },
        {
            dataIndex: ["category","name"],
            title: "类别",
            key: "category",
            filters: (localeFilter ? categories.filter(it => data.map(item => item.category?.id).includes(it.id)) : categories).map(category => {
                return {
                    text: category.name,
                    value: category.id,
                }
            }),
            onFilter: localeFilter ? (value, record) => {
                return record.category?.id == value
            } : undefined,
            filterSearch: AntdTableColumnFilterSearches.columnFilterByOptionText,
            sorter: buildSortOption((a, b) => a.category?.id ?? 0 - (b.category?.id ?? 0)),
            ellipsis:true,
        },
        {
            dataIndex: ["factory","name"],
            key: "factory",
            title: "厂商",
            filters: (localeFilter ? factories.filter(it => data.map(item => item.factory?.id).includes(it.id)) : factories).map(factory => {
                return {
                    text: factory.name,
                    value: factory.id,
                }
            }),
            onFilter: localeFilter ? (value, record) => {
                return record.factory?.id == value
            } : undefined,
            filterSearch: AntdTableColumnFilterSearches.columnFilterByOptionText,
            sorter: buildSortOption((a, b) => a.factory?.id ?? 0 - (b.factory?.id ?? 0)),
            ellipsis:true,
        },
        {
            dataIndex: "amount",
            key: "amount",
            title: "库存",
            sorter: buildSortOptionUseFieldName("amount"),
        },

        {
            dataIndex: "price",
            key: "price",
            title: "零售价",
            sorter: buildSortOptionUseFieldName("price"),
        },
        {
            key: "boxSpecification",
            dataIndex: "boxSpecification",
            title: "箱规",
            ellipsis:true,
        },
        {
            key: "recordFilingNumber",
            dataIndex: "recordFilingNumber",
            title: "备案编号",
            ellipsis:true,
        },
        {
            key: "registrationCertificateNumber",
            dataIndex: "registrationCertificateNumber",
            title: "注册证编号",
            ellipsis:true,
        },
        {
            key: "executiveStandard",
            dataIndex: "executiveStandard",
            title: '执行标准',
            ellipsis:true,
        },

    ]
    let navigate = useNavigate();
    let globalStyle = useGlobalStyle();
    const tableRef = useRef<TableRef>(null);

    return (
        <>
            <ConfigProvider componentSize={"small"}>
                <Table<T>{...props}
                         className={globalStyle.rowClickableTable}
                         size={"small"}
                         dataSource={data ?? []}
                         onRow={(data, index) => {
                             return {
                                 onClick() {
                                     navigate(`/goods/${data.id}`)
                                 },
                             }
                         }}
                         ref={tableRef}
                         scroll={{x: document.body.clientWidth, ...props.scroll}}
                         columns={props.customColumns ? props.customColumns(columns) : columns}
                         rowKey={props.rowKey ?? "id"}>
                </Table>
            </ConfigProvider>
        </>
    )
}

export default GoodsTable
